from django import http
from django.shortcuts import render

# Create your views here.
from django.views import View

from apps.verification.constants import IMAGE_CODE_EXPIRE_TIME, SMS_CODE_EXPIRE_TIME, SMS_CODE_FLG_TIME
from libs.captcha.captcha import captcha
from django_redis import get_redis_connection
import logging
from random import randint

from libs.yuntongxun.sms import CCP
from utils.response_code import RETCODE

"""
一、把需求写下来（前端需要做什么，后端要做什么）
    前端：通过一个uuid来生成一个key
    后端：生成图片验证码
    
二、把后端的思路梳理一下（把能够想到的步骤写下来）
    1.生成二进制验证码图片和验证码
    2.记录下来的验证码有一个有效期（redis，因为会经常访问）
        mysql
        redis
    3.把图片返回回去
三、确定请求方式和路由
    GET  register/？uuid=xxxx             image_codes/(?P<uuid>[\w-]+)/
    GET  register/uuid/

"""


# 生成图片验证码
class ImageCodeView(View):
    def get(self, request, uuid):
        # 1.生成二进制验证码图片和验证码
        name, code, image = captcha.generate_captcha()
        # 2.记录下来的验证码有一个有效期（redis，因为会经常访问）
        conn = get_redis_connection('code')
        # 设置图片过期时间
        # conn.setex(key,senconds,value)
        conn.setex('img:%s' % uuid, IMAGE_CODE_EXPIRE_TIME, code)
        #     mysql
        #     redis
        # 告知浏览器，以图片的像是解析
        # 如何告知：使用image_type  语法形式：大类/小类
        # MIME
        # image/jgeg  image/png   image/gif
        # application/json
        # 3.把图片返回回去
        return http.HttpResponse(image, content_type='image/jpeg')


"""
一、把需求写下来（前端需要做什么，后端需要做什么）
    前端：手机号，图形验证码，uuid
    后端：给这个手机号发送短信

二、把后端的思路梳理一下（把能够想到的步骤都写下来）
    1.接收手机号，图片验证码，uuid
    2.验证数据
    3.验证用户输入的图片验证码和我们保存的图片验证码是否一致
    4.发送短信内容
    5.保存短信内容
    6.发送短信

三、确定请求方式和路由
    GET  /wether/beijing2018            mobile/code/uuid/
         xxx/?key1=value&key2=value2;           ?mobile=xxx&code=xxxx&uuid=xxxx
         使用下面混合的方式
         /weather?d=beijing&t=2018      mobile/?code=xxxx&uuid=xxxx

"""
logger = logging.getLogger('django')


# 生成短信验证码
class SmsCodeView(View):
    def get(self, request, mobile):
        # 1.接收手机号，图片验证码，uuid
        #       因为数据在查询字符串中，所以使用下面的的查询方式
        #       image_code是用户输入的图片验证码
        image_code = request.GET.get('image_code')
        #       image_code_id  是uuid
        uuid = request.GET.get("image_code_id")
        # 2.验证数据
        if not all([image_code, uuid]):
            return http.HttpResponseBadRequest("参数不全")
        # 3.验证用户输入的图片验证码和我们保存的图片验证码是否一致
        #       我们在操作外界（例如：mysql，redis，file）的时候，我们最好进行异常捕获
        #       获取redis中的
        try:
            conn = get_redis_connection('code')
            redis_code = conn.get('img:%s' % uuid)
            # 判断是否为空
            if redis_code is None:
                return http.HttpResponseBadRequest("图片验证码已过期")
            # 对比验证码是否一致
            if redis_code.decode().lower() != image_code.decode().lower():
                return http.HttpResponseBadRequest('图片验证码输入错误')
            # 删除对比过的验证码
            conn.delete('img:%s' % uuid)
            send_flg = conn.get('send_flg:%s' % mobile)
            # redis的数据都是bytes类型
            if send_flg is not None and send_flg.decode() == 1:
                return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '哥们你操作太频繁了'})
        except Exception as e:
            logger.error(e)
            return http.HttpResponseBadRequest('redis连接错误')

            # 4.发送短信内容
        sms_code = '%06d' % randint(0, 999999)

        # 5.保存短信内容
        # conn.setex(key,seconds,value)
        # conn.setex('sms:%s' % mobile, SMS_CODE_EXPIRE_TIME, sms_code)
        # conn.setex('send_flg:%s' % mobile, SMS_CODE_FLG_TIME, 1)
        # 获取管道
        pl = conn.pipeline()
        # 让管道接管我们的redis操作
        # 保存短信内容和建立标记
        pl.setex('sms:%s' % mobile, SMS_CODE_EXPIRE_TIME, sms_code)
        pl.setex('send_flg:%s' % mobile, SMS_CODE_FLG_TIME, 1)
        # 执行管道
        pl.execute()

        # 6.发送短信
        # ccp = CCP()
        # # 注意： 测试的短信模板编号为1
        # ccp.send_template_sms(mobile, [sms_code, 5], 1)

        from celery_tasks.sms.tasks import send_sms_code
        # delay的参数 同 我们的任务参数
        send_sms_code.delay()

        return http.JsonResponse({'code': RETCODE.OK, 'error': 'OK'})
